package com.wpml.datasourcepool;

import lombok.SneakyThrows;

import javax.sql.DataSource;
import java.io.PrintWriter;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;

/**
 * @Description  自定义数据库连接池
 * @Date 2021-08-16
 * @Author wangpei
 **/
public class MyDatasource implements DataSource {

    String url = "jdbc:mysql://8.141.50.71:3306/msb_uc";
    String username = "root";
    String password = "root";

    private volatile List<Connection> pool = new LinkedList<>();

    // 代码块
    {
        try {
            Class.forName("com.mysql.jdbc.Driver");

            for (int i = 0; i < 1; i++) {
                Connection connection = DriverManager.getConnection(url, username, password);
                Connection connectionProxy = (Connection) Proxy.newProxyInstance(MyDatasource.class.getClassLoader(),
                        new Class[]{Connection.class},
                        new MyInvocationHandler(connection, pool));
                pool.add(connectionProxy);
            }

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("数据库初始化失败");
            System.exit(-1);
        }
    }

    public static void main(String[] args) throws Exception {
        MyDatasource myDatasource = new MyDatasource();

        Connection connection = myDatasource.getConnection();
        System.out.println(Thread.currentThread().getId() + " connection " + connection);

        new Thread(() -> {
            try {
                Connection connection1 = myDatasource.getConnection();
                System.out.println(Thread.currentThread().getId() + " connection1 " + connection1);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }).start();

        TimeUnit.SECONDS.sleep(3);

//        Connection connection1 = myDatasource.getConnection();

        connection.close();

        System.in.read();



    }

    long startTime = 0;
    long endTime = 0;

    @Override
    public Connection getConnection() throws SQLException {

        startTime = System.currentTimeMillis();
        // 连接池无连接时，尝试获取，
        while (pool.isEmpty() && (endTime -startTime <= 2000)) {
            endTime = System.currentTimeMillis();
        }
        System.out.println("startTime = " + startTime + "， endTime = " + endTime + ", " + (endTime -startTime));
        // 2秒内未获取到连接抛出异常
        if (endTime -startTime > 2000 && pool.isEmpty()) {
            throw new SQLException("无连接可用");
        }
        Connection connection = pool.remove(0);
        System.out.println("pool size : " + pool.size());
        return connection;
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return null;
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {

    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {

    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }
}
